package com.cea.papyrus.diagram.classdiagram.editpart;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.uml2.uml.ClassifierTemplateParameter;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.TemplateParameter;

import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.core.editpart.GraphNodeWithSemanticEditPart;
import com.cea.papyrus.core.figures.LabelFigure;
import com.cea.papyrus.core.figures.TemplateParameterFigure;
import com.cea.papyrus.core.helper.ModelerHelper;
import com.cea.papyrus.core.utils.Debug;
import com.cea.papyrus.diagraminterchange2.di2.Di2Factory;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;
import com.cea.papyrus.umlutils.ICustomAppearence;

/**
 * Control class for {@link TemplateParameter}
 */
public class TemplateParameterEditPart extends GraphNodeWithSemanticEditPart {

//	/** Manager of lightweight label controlers */ 
//	private LabelControlerManager labelsMngr;

//	/** Manager for editing property. */
//	protected DirectEditManager manager;

	/**
	 * Creates a new TemplateParameterEditPart 
	 * @param graphNode parent of the graph node controlled by this edit part
	 * @param modelManager manager in charge of models, graphic and domain
	 */
	public TemplateParameterEditPart(GraphNode graphNode,ModelManager modelManager) {
		super(graphNode,modelManager);
	}

//	/*
//	* (non-Javadoc)
//	* @see com.cea.papyrus.common.editpart.GraphNodeEditPart#createEditPolicies()
//	*/
//	@Override
//	protected void createEditPolicies(){
//	super.createEditPolicies();
//	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected IFigure createFigure() {
		return new TemplateParameterFigure();
	}

//	/**
//	* Tto obtain Property Model that is associated to this controler
//	* @return the property
//	*/
//	public TemplateParameter getTemplateParameter(){
//	return (TemplateParameter)((Uml1SemanticModelBridge)(getGraphNode()).getSemanticModel()).getElement();
//	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TemplateParameter getUmlElement() {
		return (TemplateParameter)((Uml1SemanticModelBridge)(getGraphNode()).getSemanticModel()).getElement();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void refreshVisuals() {
		Debug.debug(this, "refreshvisuals", 30);
		if(getUmlElement()!=null){
			Dimension size = getGraphNode().getSize();
			Point p = getGraphNode().getPosition();
			Rectangle r = new Rectangle(p ,size);

			TemplateParameterFigure f = (TemplateParameterFigure)getFigure();
			//add Listener on the figure
			//f.setStatic(getUmlElement().isStatic());

			/** stereotypes handling */

			/** Stereotype presentation */
			String stereotypePresentation = null;
			if(getGraphNode().getSemanticModel() != null) {
				if(getGraphNode().getSemanticModel().getPresentation() != null) {
					stereotypePresentation = getGraphNode().getSemanticModel().getPresentation();
				} else {
					getGraphNode().getSemanticModel().setPresentation(ModelerHelper.TEXT_STEREOTYPE_PRESENTATION);
					stereotypePresentation = ModelerHelper.TEXT_STEREOTYPE_PRESENTATION;
				}
			}

			// Retrieve current class and figure
			org.eclipse.uml2.uml.TemplateParameter currentTemplateParameter = getUmlElement();
			if( currentTemplateParameter!=null){
				com.cea.papyrus.umlutils.Element currentElement = new com.cea.papyrus.umlutils.Element(getUmlElement());

				IFigure fig = getFigure();
				((TemplateParameterFigure) fig).refreshColors(getGraphNode());
				((LabelFigure) fig).refreshPresentation(getPresentation(), currentTemplateParameter, getGraphNode());
				boolean hasIcon  = currentElement.hasIcon();
				boolean hasShape = currentElement.hasShape();

				String stereotypes;
				stereotypes = horizontalStereotypesToDisplay();
				f.refreshStereotypes(stereotypes, getPresentation(), hasIcon, hasShape);

				if((stereotypes!="")&& 
						((stereotypePresentation != null) && (stereotypePresentation.equals(ModelerHelper.TEXT_ICON_STEREOTYPE_PRESENTATION) || 
								stereotypePresentation.equals(ModelerHelper.TEXT_STEREOTYPE_PRESENTATION)))){
					//stereotypes=stereotypes.substring(0, stereotypes.length()-2);
					f.setStereotypes(stereotypes);//add stereotypes on the operation figure
				}
				else {
					f.setStereotypes(null);
				}

			}
			//com.cea.utils.Property utilProperty = new com.cea.utils.Property(this.getUmlElement());

			// default label
			//TODO modify this from preferences store; not UML default...
			int style = ICustomAppearence.DEFAULT_UML_PROPERTY;
			// get properties on graph node for property: custom display
			String value = getProperty(ICustomAppearence.CUSTOM_APPEARENCE_KEY);
			if(value == null) {
				com.cea.papyrus.diagraminterchange2.di2.Property prop = Di2Factory.eINSTANCE.createProperty();
				getGraphNode().getProperty().add(prop);
				prop.setKey(ICustomAppearence.CUSTOM_APPEARENCE_KEY);
				value = ""+ICustomAppearence.DEFAULT_UML_PROPERTY;
				prop.setValue(value);
			}
			if(value != null) {
				try {
					style = Integer.parseInt(value);
				} catch (NumberFormatException e) {
					Debug.log(e);
				}
			}



			// set new text
			String parameteredElementName = null ;
			String parameteredElementKind = null ;
			String defaultElementName = "" ;
			String constrainingClassifierName = "" ; // only used in the case of a ClassifierTemplateParameter
			String label = "<UNDEFINED>" ;
			if (currentTemplateParameter.getDefault() != null) {
				defaultElementName = " = " + ((NamedElement)currentTemplateParameter.getDefault()).getName() ;
			}
			if (currentTemplateParameter instanceof ClassifierTemplateParameter) {
				if (((ClassifierTemplateParameter)currentTemplateParameter).getConstrainingClassifier() != null ) {
					constrainingClassifierName = " > " + ((NamedElement)(((ClassifierTemplateParameter)currentTemplateParameter).getConstrainingClassifier())).getName() ;
				}
			}
			if (currentTemplateParameter.getParameteredElement()!=null) {
				NamedElement parameteredElement = (NamedElement)currentTemplateParameter.getParameteredElement() ;
				parameteredElementName = parameteredElement.getName() ;
				parameteredElementKind = ((EObject)parameteredElement).eClass().getName() ;
				label = parameteredElementName + " : " + parameteredElementKind + constrainingClassifierName + defaultElementName ;
			}
			f.display(label);

			((GraphicalEditPart) getParent()).setLayoutConstraint(
					this,
					f,
					r);
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void activate() {
		if (isActive()) {
			return;
		}
		super.activate();

		if (getUmlElement().getParameteredElement()!=null) {
			((Notifier)getUmlElement().getParameteredElement()).eAdapters().add(_adapter);
		}

		if (getUmlElement().getOwnedParameteredElement()!=null) {
			((Notifier)getUmlElement().getParameteredElement()).eAdapters().add(_adapter);
		}

		if (getUmlElement().getOwnedDefault() != null) {
			((Notifier)getUmlElement().getOwnedDefault()).eAdapters().add(_adapter);
		}

		if (getUmlElement().getDefault() != null) {
			((Notifier)getUmlElement().getDefault()).eAdapters().add(_adapter);
		}

		if (getUmlElement() instanceof ClassifierTemplateParameter) {
			ClassifierTemplateParameter ctp = (ClassifierTemplateParameter)getUmlElement() ;
			if (ctp.getConstrainingClassifier()!=null) {
				((Notifier)ctp.getConstrainingClassifier()).eAdapters().add(_adapter);
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void deactivate() {
		if (!isActive()) {
			return;
		}

		if (getUmlElement().getParameteredElement()!=null) {
			((Notifier)getUmlElement().getParameteredElement()).eAdapters().remove(_adapter);
		}

		if (getUmlElement().getOwnedParameteredElement()!=null) {
			((Notifier)getUmlElement().getParameteredElement()).eAdapters().remove(_adapter);
		}

		if (getUmlElement().getOwnedDefault() != null) {
			((Notifier)getUmlElement().getOwnedDefault()).eAdapters().remove(_adapter);
		}

		if (getUmlElement().getDefault() != null) {
			((Notifier)getUmlElement().getDefault()).eAdapters().remove(_adapter);
		}

		if (getUmlElement() instanceof ClassifierTemplateParameter) {
			ClassifierTemplateParameter ctp = (ClassifierTemplateParameter)getUmlElement() ;
			if (ctp.getConstrainingClassifier()!=null) {
				((Notifier)ctp.getConstrainingClassifier()).eAdapters().remove(_adapter);
			}
		}

		super.deactivate();
	}

//	protected PropertyFigure getPropertyFigure(){
//	return (PropertyFigure)createFigure() ;
//	}

//	/* (non-Javadoc)
//	* @see com.ibm.itso.sal330r.gefdemo.edit.NetworkElementEditPart#getPropertySource()
//	*/
//	@Override
//	protected IPropertySource getPropertySource() {
//	if( propertySource == null ) {
//	propertySource = new EObjectPropertySource( this.getTemplateParameter());
//	}
//	return propertySource;

//	}

//	/**
//	* Init the labels Manager and register label controlers.<p>
//	* This method should be called when a Direct Edit request is performed.
//	*/
//	protected void initLabelControlerManager() {
//	if( labelsMngr != null ) {
//	return;
//	}

//	// Create and init it.
//	labelsMngr = new LabelControlerManager();
//	labelsMngr.createLabelControler( ((PropertyFigure)getFigure()), 
//	new PropertyAccessor(){
//	public String getValue() { return "titiTOTO";}//getProperty().getName(); }
//	public void setValue(String value) {
//	//getProperty().setName(value); 
//	}
//	});
//	}

//	/**
//	* the direct edit mechanism requires the edit part to handle the direct edit
//	* request. This method determines which label the user clicked on. The label
//	* is passed to the ConditionessionCellEditorLocator which positions the cell editor 
//	* over the selected label.
//	*/
//	public void performDirectEdit(Request req) {
//	com.cea.utils.Property utilProperty = new com.cea.utils.Property(getProperty());
//	PropertyLabelEditorDialog dialog = new PropertyLabelEditorDialog(
//	PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
//	getProperty(),
//	utilProperty.getLabel()
//	);
//	final int code = dialog.open();

//	if (code == Window.OK) {
//	PropertyGenerator generator = new PropertyGenerator(getProperty());
//	try{
//	generator.parseAndModifyProperty(dialog.getValue());

//	} catch (RecognitionException e) {
//	Debug.log(e);
//	} catch (TokenStreamException e) {
//	Debug.log(e);
//	}
//	}
//	}

//	/* (non-Javadoc)
//	* @see org.eclipse.gef.editparts.AbstractEditPart#performRequest(org.eclipse.gef.Request)
//	*/
//	@Override
//	public void performRequest(Request request){
//	if (request.getType() == RequestConstants.REQ_DIRECT_EDIT) {
//	performDirectEdit(request);
//	}
//	}

	/**
	 * No direct edition by default for this edit part. this method always returns <code>false</code>.
	 */
	@Override
	protected boolean checkDefaultEdition() {
		return false;
	}

	/**
	 * Returns the presentation of the node (full display or short label)
	 * @return the string corresponding to the representation of the node
	 */
	@Override
	public String getPresentation() {
		String presentation = getGraphNode().getSemanticModel().getPresentation();
		// default value = "". it is set to null by the tool
		if(presentation == null) {
			presentation = "";
			setPresentation(presentation);
		}
		return presentation;
	}

	/**
	 * Set the new presentation for the node, then refresh display
	 * @param presentation the new presentation
	 */
	public void setPresentation(String presentation) {
		getGraphNode().getSemanticModel().setPresentation(presentation);
		refresh();
	}


}